#!/usr/bin/env python
#coding:utf-8
# TEST

import curses, pygtk, gtk, os, urllib2, time
from os import system
from  ConfigParser import *
from os.path import expanduser
pygtk.require('2.0')

#Работа с буфером обмена
def clipboardget():
    clipboard = gtk.clipboard_get()
    global cl_link
    cl_link = clipboard.wait_for_text()
    global nullcl_link
    nullcl_link =  str("0" if cl_link is None or "" else cl_link) #Отбраковывание пустого буфера
    defence()


#Защита от дурака №1
def defence():
    if nullcl_link == "0":
        window("Ошибка: буфер обмена ничего не содержит")
    if cl_link[:4] == "http" or cl_link[:3] == "ftp" or cl_link[:3] == "www":
        window(cl_link)
    else:
        window("Ошибка: текст в буфере обмена не ссылка")


#Защита от дурака №2 непосредственно перед скачкой.
#
#link = ссылка
def postdefence(link):
    if link == None or link == "":
        return 0
    elif link[:4] == "http" or link[:3] == "ftp" or link[:3] == "www":
        return 1
    else:
        return 0
 

#Сама закачка
#
#link = ссылка, typeofdownload = вид закачки, откуда вызывается(буфер, кастомная, последняя скачка или история), tries = количество попыток.
def download(link, typeofdownload, again, tries):
    if typeofdownload == "clipboard" or typeofdownload == "custom":
        enable_verify = 1
    else: #Если закачка вызывается из истории - то и нечего её проверять на правильность
        enable_verify = 0
        approved = 1
        
    if enable_verify  == 1:
        verify = postdefence(link)
        if verify == 0 and typeofdownload == "clipboard":
            linkerror(1)
            approved = 0
        elif verify == 0 and typeofdownload == "custom":
            linkerror(0)
            approved = 0
        else:
            approved = 1
    
    if approved == 1:
        writer(link, "download")
        command = os.system("wget -c -P " + savedir + " " + str(link))
        print ""
        if command == 0:
            writer(link, "success")
            print bold + "Файл успешно закачан" + normal
            raw_input("Для продолжения нажмите Enter")
        elif again == 0:
            os.system("clear")
            custom_window("redownload", link, tries)
        elif again == 1:
            redownload(link, tries)
        print ""


#Модуль показа истории, скачки из неё и вызова последней закачки
#
#quiet = тихий-ли режим (без вывода текста) или нет, to_download = порядковый номер ссылки для закачки из истории, is_for_last = интересует-ли пользователя запуск последней закачки
def history(quiet, to_download, is_for_last):
    if is_for_last == 1: #Запуск последней соверешённой скачки
        reader = open(lastfile, 'r')
        for line in reader:
            last_link = line
        download(last_link, "last", 0, 0)
    if quiet == 0: #Первый запуск
        reader = open(historyfile, 'r')
        t = 1
        for line in reader:
            print "(" + str(t) + ") "+ line
            t += 1
    else: #Тихий подсчёт при последующем запуске
        reader = open(historyfile, 'r')
        t = 1
        for line in reader:
            t += 1
        reader.close()
    if quiet == 1 and is_for_last == 0: #Основная часть последующего запуска
        reader = open(historyfile, 'r')
        y = 0
        for line in reader:
            history_link = line[:-1]
            y += 1
            if y == to_download:
                break
        download(history_link, "history", 0, 0)
        reader.close()
    if is_for_last == 0 and int(to_download) == 0:
        count = t - 1 #Технический счётчик линий в history
        des = raw_input("Чтобы продолжить - нажмите Enter.\nЧтобы перекачать определенный файл - введите его порядковый номер.\nДействие: ")
        if des == "": #Возврат
            None
        elif int(des) <= 0 or int(des) > count: #Защита от дурака
            print "Ошибка. Возврат в меню..."
            None
        else:
            history(1, int(des), 0) #Повторный запуск, но уже с целью перекачать из истории
  
    
#Писатель истории
#
#link = ссылка
def writer(link, type_of):
    if type_of == "success":
        wr = open(historyfile, 'a')
        wr.write(link + '\n')
        wr.close
    if type_of == "download":
        wr = open(lastfile, 'w')
        wr.write(link)
        wr.close


#Получение параметров
#
#prompt_string = строка с текстом для сообщения
def get_param(prompt_string):
     screen.clear()
     screen.border(0)
     screen.addstr(2, 2, prompt_string)
     screen.refresh()
     input = screen.getstr(10, 10, 60)
     return input


#Вывод текстов ошибок
#
#state = статус работы метода, от которого зависит текст ошибки и отрисовка главного меню.
def linkerror(state):
    screen.clear()
    screen.border(0)
    if state == 1:
        screen.addstr(2, 2, "В буфере обмена не ссылка. Закачка не возможна!")
        screen.addstr(3, 2, "Обновление данных из буфера омена и возвращение в главное меню...")
    elif state == 0:
        screen.addstr(2, 2, "Ошибка: введена не ссылка!")
        screen.addstr(3, 2, "Возвращение в главное меню...")
    elif state == 2:
        screen.addstr(2, 2, "Неизвестная науке ошибка =(!")
        screen.addstr(3, 2, "Возвращение в главное меню...")
    screen.refresh()
    time.sleep(3)
    if state == 1: # если ошибка произошла в скачке из буфера - то данные из буфера обновятся для удобства
        clipboardget()
        result == 0
    else:
        result == 1

#Главное меню
#
#printlink = ссылка из буфера
def window(printlink):
    while True:
        global screen
        screen = curses.initscr()
        screen.clear()
        screen.border(0)
        curses.start_color()
        curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
        curses.init_pair(2, curses.COLOR_RED, curses.COLOR_WHITE)
        curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_GREEN)
        screen.addstr(1, 10, "######### geThis! - терминальный менеджер загрузок #########", curses.color_pair(1))
        screen.addstr(3, 1, "Ссылка в буфере обмена:")
        screen.addstr(4, 1, str(printlink))
        screen.addstr(6, 4, "Выберите действие:")
        screen.addstr(8, 6, " 1 ", curses.color_pair(2))
        screen.addstr(8, 9, " -> Скачать из буфера")
        screen.addstr(9, 6, " 2 ", curses.color_pair(2))
        screen.addstr(9, 9, " -> Ввести адрес и скачать")
        screen.addstr(10, 6, " 3 ", curses.color_pair(2))
        screen.addstr(10, 9, " -> Показать историю закачек")
        screen.addstr(11, 6, " 4 ", curses.color_pair(2))
        screen.addstr(11, 9, " -> Обновить данные из буфера обмена")
        screen.addstr(12, 6, " ! ", curses.color_pair(2))
        screen.addstr(12, 9, " -> Запустить последнюю закачку в истории")
        screen.addstr(13, 6, " Q ", curses.color_pair(2))
        screen.addstr(13, 9, " -> Закрыть geThis!")
        screen.addstr(16, 6, " S ", curses.color_pair(3))
        screen.addstr(16, 9, " -> Настройки")
        screen.refresh()
        x = screen.getkey()
        
        if x == "1":
            curses.endwin()
            download(cl_link, "clipboard", 0, 0)
            if result == 0:
                break
        if x == '2':
            cust_link = get_param("Введите полный(http, ftp, www) адрес файла, который хотите закачать.")
            curses.endwin()
            download(cust_link, "custom", 0, 0)
        if x == '!':
            curses.endwin()
            history(1, 0 , 1)
        if x == '3':
            curses.endwin()
            history(0, 0, 0)
        if x == '4':
            curses.endwin()
            clipboardget()
            break
        if x == 'q':
            curses.endwin()
            gethisexit()
        if x == 's':
            curses.endwin()
            custom_window("settings", 0, 0)

#Набор кастомных окон
def custom_window(scr_type, temp, temp2):
    if scr_type == "redownload":
        screen.clear()
        screen.border(0)
        screen.addstr(1, 30, "Файл не был закачан!", curses.color_pair(2))
        screen.addstr(6, 4, "Выберите действие:")
        screen.addstr(8, 6, " 1 ", curses.color_pair(2))
        screen.addstr(8, 9, " -> Продолжить попытки скачивать файл")
        screen.addstr(9, 9, "    Количество попыток: ")
        if down_tries == 0:
            screen.addstr(9, 33, " бесконечно")
        else:
            screen.addstr(9, 33, " " + str(down_tries))
        screen.addstr(11, 6, " 2 ", curses.color_pair(2))
        screen.addstr(11, 9, " -> Выйти в основное меню")
        screen.refresh()
        x = screen.getkey()
        
        if x == "1":
            curses.endwin()
            redownload(temp, temp2)
        if x == '2':
            curses.endwin()
    
    if scr_type == "settings":
        screen.clear()
        screen.border(0)
        screen.addstr(1, 30, "Настройки geThis", curses.color_pair(2))
        screen.addstr(4, 4, "Выберите действие:")
        screen.addstr(6, 6, " 1 ", curses.color_pair(2))
        screen.addstr(6, 9, " -> Сменить папку для загрузок.")
        screen.addstr(7, 9, "    Текущая папка: " + savedir)
        screen.addstr(9, 6, " 2 ", curses.color_pair(2))
        screen.addstr(9, 9, " -> Указать количество попыток для перекачки.")
        if down_tries == 0:
            screen.addstr(10, 9, "    Текущее кол-во: бесконечно")
        else:
            screen.addstr(10, 9, "    Текущее кол-во: " + str(down_tries))
        screen.addstr(15, 6, " 3 ", curses.color_pair(2))
        screen.addstr(15, 9, " -> Выйти в основное меню")
        screen.refresh()
        x = screen.getkey()

        if x == "1":
            setValue("SETTINGS", "savepath", get_param("Введите путь к нужной папке. Например: ~/Downloads"))
            curses.endwin()
            custom_window("settings", 0, 0)
        if x == '2':
            setValue("SETTINGS", "tries", get_param("Введите количество попыток. 0 - бесконечно."))
            curses.endwin()
            custom_window("settings", 0, 0)
        if x == "3":
            curses.endwin()
        
#Модуль попыток повторной закачки            
def redownload(link, tries):
    try:
        os.system("clear")
        tries += 1
        if tries <= down_tries or down_tries == 0:
            spaces = 10
            for x in xrange(10):
                os.system("clear")
                chars = x
                spaces -= 1
                print bold + "Попытка №" +str(tries) + "\nСледующая попытка через [" + ("|" * chars) + (" " * spaces) + bold + "]\nДля отмены нажмите Ctrl + C\n\n" + normal
                time.sleep(1)
            download(link, "again", 1, tries)
        else:
            custom_window("redownload", link, 0)
    except KeyboardInterrupt:
        pass
        
            	
#Красивое и вежливое закрытие программы
def gethisexit():
    screen.clear()
    screen.border(0)
    screen.addstr(2, 20, "Выключение geThis!...")
    screen.addstr(3, 20, "Всего наилучшего!!!")
    screen.refresh()
    time.sleep(1.5)
    curses.endwin()
#config.close()
    exit()

#Считывание настроек
def getsettings(get_type, sect, index):
    if get_type == "str":
        return config.get(sect, index)
    elif get_type == "int":
        return config.getint(sect, index)

#Запись в настройки        
def setValue(sect, index, value):
    cfgfile = open(settsfile, 'w')
    config.set(sect, index, value)
    config.write(cfgfile)
    cfgfile.close()
    variables() #Обновление переменных и проверка на целостность

#Проверка наличия всех файлов
def creator():
    if os.path.isdir(userdir + "/.config/gethis") == False:
        os.system("cd ~/.config&&mkdir gethis")
    if os.path.isfile(userdir + "/.config/gethis/settings.ini") == False:
        with open(userdir + "/.config/gethis/settings.ini", 'w') as writer:
            writer.write('[SETTINGS]\nsavepath = ~/Загрузки\ntries = 0')
            writer.close
    if os.path.isdir(userdir + "/.config/gethis/log") == False:
        os.system("cd ~/.config/gethis&&mkdir log")
    if os.path.isfile(userdir + "/.config/gethis/log/history") == False:
        with open(userdir + "/.config/gethis/log/history", 'w') as writer:
            writer.close
    if os.path.isfile(userdir + "/.config/gethis/log/last") == False:
        with open(userdir + "/.config/gethis/log/last", 'w') as writer:
            writer.close


#Настройки и переменные
def variables():
    global userdir
    userdir = os.path.expanduser('~')

    creator()

    global settsfile
    settsfile = os.path.expanduser('~') + "/.config/gethis/settings.ini"

    global config
    config = ConfigParser()
    config.read(settsfile)

    global gdir
    gdir = os.path.expanduser('~') + "/.gethis"
    global savedir
    savedir = expanduser(getsettings("str", "SETTINGS", "savepath"))
    global historyfile
    historyfile = os.path.expanduser('~') + "/.config/gethis/log/history"
    global lastfile
    lastfile = os.path.expanduser('~') + "/.config/gethis/log/last"
    global result
    result = 1
    global down_tries
    down_tries = getsettings("int", "SETTINGS", "tries")

    #Для текста
    global bold
    bold = '\033[1m'
    global normal
    normal = '\033[0m'

#Непосредственный старт программы
variables()
clipboardget()
